package com.zyt.wiki.controller;

import com.alibaba.fastjson.JSONObject;
import com.zyt.wiki.req.UserLoginReq;
import com.zyt.wiki.req.UserQueryReq;
import com.zyt.wiki.req.UserResetPasswordReq;
import com.zyt.wiki.req.UserSaveReq;
import com.zyt.wiki.resp.CommonResp;
import com.zyt.wiki.resp.PageResp;
import com.zyt.wiki.resp.UserLoginResp;
import com.zyt.wiki.resp.UserQueryResp;
import com.zyt.wiki.service.UserService;
import com.zyt.wiki.util.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
public class UserController {

    public static final Logger LOG = LoggerFactory.getLogger(UserController.class) ;

    @Autowired
    private UserService userService ;

    @Resource
    private SnowFlake snowFlake;

    @Resource
    private RedisTemplate redisTemplate;

    @GetMapping("/list")
    public CommonResp list(@Valid UserQueryReq req){
        CommonResp<PageResp<UserQueryResp>> resp = new CommonResp<>() ;
        PageResp<UserQueryResp> pageResp = this.userService.list(req) ;
        resp.setContent(pageResp);
        return resp ;
    }

    @PostMapping("/save")
    public CommonResp save(@Valid @RequestBody UserSaveReq req){
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); // 针对前端上送密码，进行MD5加密（得到32位的16进制字符串）后再入库
        CommonResp resp = new CommonResp() ;
        this.userService.save(req) ;
        return  resp ;
    }

    @DeleteMapping("/delete/{id}")
    public CommonResp delete(@PathVariable Long id){
        CommonResp resp = new CommonResp() ;
        this.userService.delete(id) ;
        return resp ;
    }

    @PostMapping("/reset-password")
    public CommonResp resetPassword(@Valid @RequestBody UserResetPasswordReq req){
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); // 针对前端上送密码，进行MD5加密（得到32位的16进制字符串）后再入库
        CommonResp resp = new CommonResp() ;
        this.userService.resetPassword(req) ;
        return  resp ;
    }

    @PostMapping("/login")
    public CommonResp login(@Valid @RequestBody UserLoginReq req){
        req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); // 前端上送密码要进行MD5加密后，才可与库中密码进行比对
        CommonResp resp = new CommonResp() ;
        UserLoginResp userLoginResp = this.userService.login(req);

        // 用户校验成功后，生成登录token，返回前端并存入Redis（key：token，value：用户信息）
        Long token = snowFlake.nextId() ; // long自动封包成Long，方便下面转换成String类型
        LOG.info("生成单点登录token：{}，并放入redis中", token);
        userLoginResp.setToken(token.toString()) ;
        this.redisTemplate.opsForValue().set(token.toString(), JSONObject.toJSONString(userLoginResp), 60 * 15, TimeUnit.SECONDS);
        // redis中再存放一个 客户号：token，确保一个客户号只有一个token（用于登录账号互踢）
        this.redisTemplate.opsForValue().set(userLoginResp.getLoginName(), token.toString(), 60 * 15, TimeUnit.SECONDS) ;

        resp.setContent(userLoginResp);
        return resp ;
    }

    /** 退出登录 */
    @GetMapping("/logout/{token}")
    public CommonResp logout(@PathVariable String token){
        CommonResp resp = new CommonResp() ;
        LOG.info("从redis中删除token: {}", token) ;
        this.redisTemplate.delete(token) ;
        return resp ;
    }

    public static void main(String[] args) {
        String str = "test123" ;
        String md5 = DigestUtils.md5DigestAsHex(str.getBytes());
        System.out.println(md5);
        System.out.println(str.length());
        System.out.println(md5.length());
    }

}
